package com.ethink.warehouse.manager;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.ethink.warehouse.api.enums.LogisticsTraceOrderSourceEntityTypeEnum;
import com.ethink.warehouse.api.enums.LogisticsTraceOrderTransportEntityEnum;
import com.ethink.warehouse.api.enums.LogisticsTraceStepEnum;
import com.ethink.warehouse.api.info.LogisticsStepInfo;
import com.ethink.warehouse.api.request.LogisticsStepListGetRequest;
import com.ethink.warehouse.common.entity.Warehouse;
import com.ethink.warehouse.common.mapper.WarehouseMapper;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import java.util.ArrayList;
import java.util.List;
import java.util.stream.Collectors;

/**
 * @author default
 * @date 2022-11-10
 */
@Slf4j
@Component
public class LogisticsStepManager {

    @Autowired
    private WarehouseMapper warehouseMapper;

    public String getLogisticsStepString(LogisticsStepListGetRequest request) {
        List<LogisticsStepInfo> list = getLogisticsStepList(request);
        return list.stream().map(LogisticsStepInfo::getCode)
                .collect(Collectors.joining(","));
    }

    public List<LogisticsStepInfo> getLogisticsStepList(LogisticsStepListGetRequest request) {
        Warehouse sourceWarehouse = getWarehouse(request.getSourceWarehouseCode());
        Warehouse targetWarehouse = getWarehouse(request.getTargetWarehouseCode());
        List<LogisticsStepInfo> list = new ArrayList<>();
        // 跨境运输判断
        // 供应商固定为境外；客户固定为境内
        boolean sourceIsOutBound = LogisticsTraceOrderSourceEntityTypeEnum.T1.eq(request.getSourceEntityType())
                || (LogisticsTraceOrderSourceEntityTypeEnum.T3.eq(request.getSourceEntityType())
                && sourceWarehouse.getIsOutbound());
        boolean targetIsOutBound = LogisticsTraceOrderSourceEntityTypeEnum.T1.eq(request.getTargetEntityType())
                || (LogisticsTraceOrderSourceEntityTypeEnum.T3.eq(request.getTargetEntityType())
                && targetWarehouse.getIsOutbound());

        list.add(build(LogisticsTraceStepEnum.A));
        if (LogisticsTraceOrderSourceEntityTypeEnum.T3.eq(request.getSourceEntityType())
                && !sourceWarehouse.getIsVirtual()) {
            // 始发地是分仓且不是虚拟仓
            list.add(build(LogisticsTraceStepEnum.B));
        }
        if (LogisticsTraceOrderSourceEntityTypeEnum.T3.eq(request.getSourceEntityType())) {
            list.add(build(LogisticsTraceStepEnum.C));
        }
        if (LogisticsTraceOrderTransportEntityEnum.T1.eq(request.getTransportEntity())) {
            // 运输方是我方
            list.add(build(LogisticsTraceStepEnum.D));
        }
        if (LogisticsTraceOrderSourceEntityTypeEnum.T3.eq(request.getTargetEntityType())
                && LogisticsTraceOrderTransportEntityEnum.T1.eq(request.getTransportEntity())
                && (sourceIsOutBound != targetIsOutBound)
        ) {
            // 目的地是分仓且运输方是我方且是跨境运输
            list.add(build(LogisticsTraceStepEnum.E));
        }
        if (LogisticsTraceOrderSourceEntityTypeEnum.T3.eq(request.getTargetEntityType())
                && !targetWarehouse.getIsVirtual()) {
            // 目的地是分仓且不是虚拟仓
            list.add(build(LogisticsTraceStepEnum.F));
            list.add(build(LogisticsTraceStepEnum.G));
//            list.add(build(LogisticsTraceStepEnum.H));
//            list.add(build(LogisticsTraceStepEnum.H1));
//            list.add(build(LogisticsTraceStepEnum.H2));
        }
        if (LogisticsTraceOrderSourceEntityTypeEnum.T3.eq(request.getTargetEntityType())) {
            // 目的地是分仓
            list.add(build(LogisticsTraceStepEnum.H));
        }
        list.add(build(LogisticsTraceStepEnum.I));
        return list;
    }

    private Warehouse getWarehouse(String warehouseCode) {
        if (StringUtils.isBlank(warehouseCode)) {
            return null;
        }
        return warehouseMapper.selectOne(new LambdaQueryWrapper<Warehouse>()
                .eq(Warehouse::getWarehouseCode, warehouseCode));
    }

    private LogisticsStepInfo build(LogisticsTraceStepEnum stepEnum) {
        LogisticsStepInfo info = new LogisticsStepInfo();
        info.setCode(stepEnum.getCode());
        info.setName(stepEnum.getName());
        return info;
    }
}
